package org.jetnuke.modules.calendar;

import org.apache.log4j.Logger;

import java.util.Collections;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.velocity.VelocityContext;
import org.jetnuke.common.ActionForward;
import org.jetnuke.common.IAction;
import org.jetnuke.common.IAdminInfo;
import org.jetnuke.common.IModuleInfo;
import org.jetnuke.common.IUserInfo;
import org.jetnuke.dao.CalendarEventDAO;
import org.jetnuke.dao.DataAccessDriver;
import org.jetnuke.modules.calendar.utils.CalendarUtils;

public class MonthCalendar implements IAction {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(MonthCalendar.class);

	int year;
	int month;

	public void setMonth(int month) {
		this.month = month;
	}

	public void setYear(int year) {
		this.year = year;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.jetnuke.common.IAction#exec(javax.servlet.http.HttpServletRequest,
	 *      javax.servlet.http.HttpServletResponse,
	 *      org.apache.velocity.VelocityContext, org.jetnuke.common.IModuleInfo,
	 *      java.lang.String, org.jetnuke.common.IUserInfo,
	 *      org.jetnuke.common.IAdminInfo)
	 */
	public ActionForward exec(HttpServletRequest request,
			HttpServletResponse response, VelocityContext vc, IModuleInfo info,
			String op, IUserInfo ui, IAdminInfo ai) throws Exception {
		if (logger.isDebugEnabled()) {
			logger
					.debug("exec(HttpServletRequest, HttpServletResponse, VelocityContext, IModuleInfo, String, IUserInfo, IAdminInfo) - start"); //$NON-NLS-1$
		}

		if (ui == null || ui.getID() < 2)
			return null;

		if (year == 0 || month == 0) {
			GregorianCalendar gc = new GregorianCalendar();
			year = gc.get(java.util.Calendar.YEAR);
			month = gc.get(java.util.Calendar.MONTH) + 1;
		}

		HashMap days = new HashMap();
		CalendarUtils.putCommonObjects(vc);
		// int subtract=getFirstDayOfWeek();

		String current_month = String.valueOf(month);
		if (current_month.length() == 1) {
			current_month = "0" + current_month;
		}
		vc.put("current_month", current_month);
		GregorianCalendar gc = getFirstDayOnCalendar(year, month - 1);
		GregorianCalendar dt = gc;
		for (int i = 0; i < 6; i++) {
			for (int j = 0; j < 7; j++) {
				GregorianCalendar tmp = new GregorianCalendar();
				tmp.setTime(dt.getTime());
				days.put(new Integer(i + j * 7), tmp);
				dt.add(java.util.Calendar.DATE, 1);
			}
		}
		vc.put("days", days);
		List month_days = CalendarUtils.getDaysOfMonth(year, month);
		vc.put("month_days", month_days);
		HashMap events = new HashMap();
		CalendarEventDAO cedao = DataAccessDriver.getInst()
				.newCalendarEventDAO();
		List recurringEvents = cedao.selectPeriodRecurringEvents(ui.getID(),
				(GregorianCalendar) month_days.get(0),
				(GregorianCalendar) month_days.get(month_days.size() - 1));
		Iterator it_day = month_days.iterator();
		while (it_day.hasNext()) {
			GregorianCalendar day_ = (GregorianCalendar) it_day.next();
			List dayEvents = cedao.selectDayEvents(ui.getID(), day_);
			List activeRecurringEventDay = CalendarUtils
					.getActiveRecurringEvent(recurringEvents, day_);
			dayEvents.addAll(activeRecurringEventDay);
			Collections.sort(dayEvents);
			events.put(day_, dayEvents);
		}
		vc.put("events", events);
		int nextYear = year;
		int previousYear = year;
		int nextMonth = month + 1;
		if (nextMonth > 12) {
			nextMonth = 1;
			nextYear += 1;
		}
		int previousMonth = month - 1;
		if (previousMonth < 1) {
			previousYear -= 1;
			previousMonth = 12;
		}
		vc.put("previousMonth", new Integer(previousMonth));
		vc.put("nextMonth", new Integer(nextMonth));
		vc.put("previousYear", new Integer(previousYear));
		vc.put("nextYear", new Integer(nextYear));
		vc.put("currentMonthDes", ((List) vc.get("MONTHS")).get(month - 1));
		vc.put("year", new Integer(year));
		ActionForward returnActionForward = new ActionForward(op, info);
		if (logger.isDebugEnabled()) {
			logger
					.debug("exec(HttpServletRequest, HttpServletResponse, VelocityContext, IModuleInfo, String, IUserInfo, IAdminInfo) - end"); //$NON-NLS-1$
		}
		return returnActionForward;
	}

	public GregorianCalendar getFirstDayOnCalendar(int year_, int month_) {
		if (logger.isDebugEnabled()) {
			logger.debug("getFirstDayOnCalendar(int, int) - start"); //$NON-NLS-1$
		}

		GregorianCalendar g = new GregorianCalendar(year_, month_, 1);
		int dow = g.get(java.util.Calendar.DAY_OF_WEEK);

		if (dow != 1)
			g.add(java.util.Calendar.DATE, ((dow - 1) * -1));

		if (logger.isDebugEnabled()) {
			logger.debug("getFirstDayOnCalendar(int, int) - end"); //$NON-NLS-1$
		}
		return g;
	}

}
